package com.sun.api;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.Iterator;

@RestController
public class RedisTemplateZset {

    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/zset")
    public String testZset() {
        // 添加元素，有序集合按照score的值从小到大排序
        redisTemplate.opsForZSet().add("zset", "第一个zset", 100);
        redisTemplate.opsForZSet().add("zset", "第二个zset", 110);
        redisTemplate.opsForZSet().add("zset", "第三个zset", 120);
        redisTemplate.opsForZSet().add("zset", "第四个zset", 130);
        redisTemplate.opsForZSet().add("zset", "第五个zset", 140);

        // 获取元素在集合中的排名，按照score值从小到大排序
        System.out.println("从小到大：" + redisTemplate.opsForZSet().rank("zset", "第二个zset"));

        // 获取元素在集合中的排名，按照score值从大到小排序
        System.out.println("从大到小：" + redisTemplate.opsForZSet().reverseRank("zset", "第二个zset"));

        System.out.println("--------------------------------------");

        // 获取集合中给定区间的元素，start开始位置，end结束位置，-1查询所有(从小到大)
        // 返回值为:Set<ZSetOperations.TypedTuple<V>>
        Iterator iterator = redisTemplate.opsForZSet().rangeWithScores("zset", 0, -1).iterator();
        while (iterator.hasNext()) {
            ZSetOperations.TypedTuple typedTuple = (ZSetOperations.TypedTuple) iterator.next();
            System.out.println("从小到大：" + typedTuple.getValue() + ", " + typedTuple.getScore());
        }

        System.out.println("--------------------------------------");

        // 获取集合中给定区间的元素，start开始位置，end结束位置，-1查询所有（从大到小）
        Iterator iterator3 = redisTemplate.opsForZSet().reverseRangeWithScores("zset", 0, -1).iterator();
        while (iterator3.hasNext()) {
            ZSetOperations.TypedTuple typedTuple3 = (ZSetOperations.TypedTuple) iterator3.next();
            System.out.println("从大到小：" + typedTuple3.getValue() + ", " + typedTuple3.getScore());
        }

        System.out.println("--------------------------------------");

        // 按照score值查询集合中的元素，结果从小到大排序
        System.out.println("从小到大：" + redisTemplate.opsForZSet().rangeByScore("zset", 100, 200));
        Iterator iterator4 = redisTemplate.opsForZSet().rangeByScoreWithScores("zset", 100, 200).iterator();
        while (iterator4.hasNext()) {
            ZSetOperations.TypedTuple typedTuple4 = (ZSetOperations.TypedTuple) iterator4.next();
            System.out.println("从小到大：" + typedTuple4.getValue() + ", " + typedTuple4.getScore());
        }

        System.out.println("--------------------------------------");


        // 按照score值查询集合中的元素，结果从大到小排序
        System.out.println("从大到小：" + redisTemplate.opsForZSet().reverseRangeByScore("zset", 100, 200));
        Iterator iterator5 = redisTemplate.opsForZSet().reverseRangeByScoreWithScores("zset", 100, 200).iterator();
        while (iterator5.hasNext()) {
            ZSetOperations.TypedTuple typedTuple5 = (ZSetOperations.TypedTuple) iterator5.next();
            System.out.println("从大到小：" + typedTuple5.getValue() + ", " + typedTuple5.getScore());
        }

        System.out.println("--------------------------------------");

        // 从大到小排序获取集合中score在给定最大最小范围内的元素
        System.out.println("从大到小：" + redisTemplate.opsForZSet().reverseRangeByScore("zset", 100, 1000, 0, -1));

        System.out.println("--------------------------------------");

        // 根据score获取集合元素数量
        System.out.println(redisTemplate.opsForZSet().count("zset", 100, 150));

        System.out.println("--------------------------------------");

        // 获取集合大小
        System.out.println(redisTemplate.opsForZSet().size("zset"));
        System.out.println(redisTemplate.opsForZSet().zCard("zset"));

        System.out.println("--------------------------------------");

        // 获取集合中key value 对应的score
        System.out.println(redisTemplate.opsForZSet().score("zset", "第三个zset"));

        System.out.println("--------------------------------------");

        // 移除指定索引位置的元素
        redisTemplate.opsForZSet().removeRange("zset", 0, 1);
        System.out.println(redisTemplate.opsForZSet().range("zset", 0, -1));

        System.out.println("--------------------------------------");

        // 获取key 和otherKey的交集并存储在targetKey
        redisTemplate.opsForZSet().add("otherZset", "第二个zset", 200);
        redisTemplate.opsForZSet().add("otherZset", "第三个zset", 200);
        redisTemplate.opsForZSet().intersectAndStore("zset", "otherZset", "targetZset");
        System.out.println(redisTemplate.opsForZSet().range("targetZset", 0, -1));

        System.out.println("--------------------------------------");

        // 获取key和otherKey的并集并且存储在targetKey中
        redisTemplate.opsForZSet().unionAndStore("zset", "otherZset", "fourthZset");
        System.out.println(redisTemplate.opsForZSet().range("fourthZset", 0, -1));

        System.out.println("--------------------------------------");

        // 遍历集合
        try {
            Cursor<ZSetOperations.TypedTuple> cursor = redisTemplate.opsForZSet().scan("zset", ScanOptions.NONE);
            while (cursor.hasNext()) {
                ZSetOperations.TypedTuple typedTuple = cursor.next();
                System.out.println(typedTuple.getValue() + ", " + typedTuple.getScore());
            }
            cursor.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}
